package com.tvunetworks.center.device.service.impl;

import com.fasterxml.jackson.databind.JsonNode;
import com.tvunetworks.center.common.constant.LocalConstant;
import com.tvunetworks.center.common.exception.ServerException;
import com.tvunetworks.center.common.model.GetTpcFeatureEnableParam;
import com.tvunetworks.center.common.model.LoginUser;
import com.tvunetworks.center.common.model.dto.MsgpipeDTO;
import com.tvunetworks.center.common.model.dto.grid.GridResult;
import com.tvunetworks.center.common.model.param.PeerIdParam;
import com.tvunetworks.center.common.model.vo.TimeLockDeviceMsgVo;
import com.tvunetworks.center.common.util.JsonUtil;
import com.tvunetworks.center.common.util.MyUtil;
import com.tvunetworks.center.common.util.Result;
import com.tvunetworks.center.common.util.ResultUtil;
import com.tvunetworks.center.device.constant.CommandConstant;
import com.tvunetworks.center.device.constant.DeviceConstant;
import com.tvunetworks.center.device.mapper.TimeLockEventMapper;
import com.tvunetworks.center.device.model.MyDevice;
import com.tvunetworks.center.device.model.TimeLockEvent;
import com.tvunetworks.center.device.model.TimeLockMsg;
import com.tvunetworks.center.device.model.dto.TimeLockBody;
import com.tvunetworks.center.device.model.json.SetBitrateAndDelayParam;
import com.tvunetworks.center.device.model.param.TimeLockSyncParam;
import com.tvunetworks.center.device.model.param.TimeLockUpdateSyncParam;
import com.tvunetworks.center.device.model.result.ResultConstant;
import com.tvunetworks.center.device.model.vo.DeviceIdNameAndMsg;
import com.tvunetworks.center.device.model.vo.TimeLockDeviceVo;
import com.tvunetworks.center.device.model.vo.TimeLockMsgResult;
import com.tvunetworks.center.device.model.vo.TimeLockMsgVO;
import com.tvunetworks.center.device.service.*;
import com.tvunetworks.center.device.service.feign.UserFeignService;
import com.tvunetworks.center.device.util.RedisLock;
import com.tvunetworks.center.gs.model.Device;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.io.IOException;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @program: tvucc-aggregator
 * @description: TimeLockEventServiceImpl
 * @author lebronchen
 * @create: 2019-03-26 10:30
 **/
@Service
@Slf4j
public class TimeLockEventServiceImpl extends BaseService<TimeLockEvent> implements TimeLockEventService {

    @Autowired
    private ReceiverControlService receiverControlService;
    @Autowired
    private DeviceService deviceService;
    @Autowired
    private TimeLockEventMapper timeLockEventMapper;
    @Autowired
    private UserFeignService userFeignService;
    @Autowired
    private TimeLockMsgService timeLockMsgService;
    @Autowired
    private UserBehaviorService userBehaviorService;
    @Autowired
    private RedisLock redisLock;
    @Autowired
    private UserDeviceService userDeviceService;

    @Value("${timelock.check.tpc.feature}")
    private boolean timeLockCheckTpcFeature;
    @Value("${enableProcessTimeLockMessage}")
    private boolean enableProcessTimeLockMessage;

    @Override
    @Transactional
    public Result<String> synchronize(String userId, TimeLockSyncParam param) {
        String redisKey = "time:lock:sync:" + userId;
        try {
            redisLock.lock(redisKey);
            param.setMainPeerId(param.getMainPeerId().toLowerCase());
            param.setPackPeerId(param.getPackPeerId().toLowerCase());
            param.setSyncPeerIds(param.getSyncPeerIds().stream().map(String::toLowerCase).collect(Collectors.toList()));
            //0.校验syncDevice是否满足需求
            String mainPeerId = param.getMainPeerId();
            List<String> synPeerIdList = param.getSyncPeerIds();
            Map<String, String> packDependenceRidMap = new HashMap<>();
            //校验参数并获取所有的Receiver
            List<Device> rDevices = this.checkSyncReceiverAndPackAndGetReceiver(synPeerIdList, param.getPackPeerId(), packDependenceRidMap);
            packDependenceRidMap.put(param.getPackPeerId(), param.getMainPeerId());
            //1.获取主R内网外网Ip/Port
            TimeLockMsgVO timeLockMsg = this.getReceiverIpAndPort(mainPeerId);
            //2.获取其它设备的所有内网Ip
            List<Map<String, String>> peerIdAndIntranetIps = this.getIntranetIps(rDevices, timeLockMsg.getIntranetIp(), mainPeerId);
            Map<String, String> intranetIps = peerIdAndIntranetIps.get(0);
            intranetIps.put(timeLockMsg.getIntranetIp(), mainPeerId);
            Map<String, String> peerIdsMap = peerIdAndIntranetIps.get(1);
            peerIdsMap.put(mainPeerId, timeLockMsg.getIntranetIp());
            //3.校验需要Sync的R/Pack是否已经存在了
            TimeLockEvent timeLockEvent = new TimeLockEvent();
            timeLockEvent.setUserId(userId);
            timeLockEvent.setType(DeviceConstant.TimeLockEventType.START_SYNC);
            //3.1.校验是否已经Sync中
            List<TimeLockEvent> existTimeLocks = super.selectExistList(timeLockEvent);
            if (!CollectionUtils.isEmpty(existTimeLocks)) {
                throw new ServerException(ResultConstant.TimeLock.SYNCHRONIZING);
            }
            //3.2.校验device是否已经添加过timeLock或同步的R是否有相同的Ip已经同步
            List<String> allPeerIds = this.checkDeviceSynchronizing(mainPeerId, synPeerIdList, intranetIps, new ArrayList<>(), Boolean.TRUE, null);
            //4.校验设备是否含有TimeLockFeature
            this.checkTimeLockFeatureExist(allPeerIds);
            //5.保存 TimeLockEvent入库
            super.insert(timeLockEvent);
            //6.report TimeLockMsg入库
            String eventId = timeLockEvent.getId();
            timeLockMsgService.reportTimeLockMsg(eventId, mainPeerId, synPeerIdList, peerIdsMap, packDependenceRidMap);
            //7.start TimeLockMsg入库 并且发送msgpipe消息
            timeLockMsgService.startTimeLockMsg(eventId, mainPeerId, synPeerIdList, timeLockMsg, peerIdsMap, packDependenceRidMap);
            //8.添加user behavior
            userBehaviorService.setUserTimeLockBehavior(userId, true);
            return ResultUtil.success();
        } finally {
            redisLock.unlock(redisKey);
        }
    }

    /**
     * 校验从R/Pack是否正确，以及是否按照指定规制(R,T,R,T)排序的
     *
     * @param syncPeerIds    除了主RLive的pack之外的所以T/R
     * @param syncPackPeerId 主R配对的Pack
     * @param packDependenceRidMap key为pack，value为R
     * @return 所有从R/T对应的device
     */
    private List<Device> checkSyncReceiverAndPackAndGetReceiver(List<String> syncPeerIds, String syncPackPeerId, Map<String, String> packDependenceRidMap) {
        //1.校验参数是否正确
        if (CollectionUtils.isEmpty(syncPeerIds)) {
            throw new ServerException(ResultConstant.TimeLock.RECEIVER_COUNT_MUST_MORE_THAN_ONE);
        }
        Set<String> peerIdSet = new HashSet<>(syncPeerIds);
        if (syncPeerIds.size() != peerIdSet.size() || syncPeerIds.size() % 2 == 1) {
            throw new ServerException(ResultConstant.TimeLock.NUMBER_OF_PACKS_AND_RECEIVERS_IS_INCONSISTENT);
        }
        List<Device> devices = new ArrayList<>();
        StringBuilder sb = new StringBuilder();
        List<String> notExist = new ArrayList<>();
        List<String> notPack = new ArrayList<>();
        List<String> versions = new ArrayList<>();
        //校验pack/receiver 是否存在已经版本是否大于6.1或者是否为 R/Pack
        for (int i = 0; i < syncPeerIds.size(); i++) {
            Device device = deviceService.getCurrentDevice(syncPeerIds.get(i));
            if (device == null) {
                notExist.add(syncPeerIds.get(i));
                continue;
            }
            if (!StringUtils.equalsIgnoreCase(LocalConstant.DeviceType.R, device.getType())
                    && !StringUtils.equalsIgnoreCase(LocalConstant.DeviceType.T, device.getType())) {
                notPack.add(device.getName());
                continue;
            }
            if (!this.checkVersion(device.getVersion())) {
                versions.add(device.getName());
                continue;
            }
            if (i % 2 == 0) {
                if (!StringUtils.equalsIgnoreCase(LocalConstant.DeviceType.R, device.getType())) {
                    throw new ServerException(ResultConstant.TimeLock.PARAMETER_IS_INCORRECT);
                }
            } else {
                if (!StringUtils.equalsIgnoreCase(LocalConstant.DeviceType.T, device.getType())) {
                    throw new ServerException(ResultConstant.TimeLock.PARAMETER_IS_INCORRECT);
                }
                packDependenceRidMap.put(syncPeerIds.get(i), syncPeerIds.get(i - 1));
            }
            devices.add(device);
        }
        if (StringUtils.isNotEmpty(syncPackPeerId)) {
            Device device = deviceService.getCurrentDevice(syncPackPeerId);
            if (device == null) {
                notExist.add(syncPackPeerId);
            } else if (!StringUtils.equalsIgnoreCase(LocalConstant.DeviceType.R, device.getType())
                    && !StringUtils.equalsIgnoreCase(LocalConstant.DeviceType.T, device.getType())) {
                notPack.add(device.getName());
            } else if (!this.checkVersion(device.getVersion())) {
                versions.add(device.getName());
            }
            syncPeerIds.add(syncPackPeerId);
        }
        if (!CollectionUtils.isEmpty(notExist)) {
            sb.append(notExist).append(" these device not exist");
        }
        if (!CollectionUtils.isEmpty(notPack)) {
            sb.append(notPack).append(" These device is not Pack Or Receiver,TimeLock just support Pack or Receiver");
        }
        if (!CollectionUtils.isEmpty(versions)) {
            sb.append(notPack).append(" These device Version less 6.1");
        }
        if (StringUtils.isNotEmpty(sb.toString())) {
            throw new ServerException(ResultConstant.TimeLock.PARAMETER_IS_INCORRECT.setErrorInfo(sb.toString()));
        }
        //3.获取所有Receiver
        devices = devices.stream().filter(s -> StringUtils.equalsIgnoreCase(s.getType(), LocalConstant.DeviceType.R))
                .collect(Collectors.toList());
        if (CollectionUtils.isEmpty(devices)) {
            throw new ServerException(ResultConstant.TimeLock.RECEIVER_COUNT_MUST_MORE_THAN_ONE);
        }
        return devices;
    }

    /**
     * 校验version是否大于等于6.1
     * @param version version号
     * @return true表示大于等于，false表示小于
     */
    private boolean checkVersion(String version) {
        if (StringUtils.isNotEmpty(version)) {
            if (version.length() > 3) {
                version = version.substring(0, 3);
            }
            return Double.parseDouble(version) >= 6.1;
        }
        return false;
    }

    /**
     * 校验是否已经正在synchronization中，如果存在，则报错
     *
     * @param mainPeerId    主R
     * @param synPeerIdList 从R/Pack的集合
     * @param intranetIps   从R对应的Ip集合
     * @param excludePeerId 校验内网ip排除之外的rid
     * @param checkMainRid  是否需要校验mainR
     * @param eventId  去除相同的eventId
     * @return 所有R/Pack的集合
     */
    private List<String> checkDeviceSynchronizing(String mainPeerId, List<String> synPeerIdList, Map<String, String> intranetIps,
                                                  List<String> excludePeerId, boolean checkMainRid, String eventId) {

        //1.检查是否存在需要同步的设备正在TimeLock
        List<String> allPeerIds = new ArrayList<>();
        if (checkMainRid) {
            allPeerIds.add(mainPeerId);
        }
        allPeerIds.addAll(synPeerIdList);
        List<String> synchronizingList = timeLockEventMapper.listSynchronizingDevice(allPeerIds);
        if (!CollectionUtils.isEmpty(synchronizingList)) {
            String names = this.getDeviceNameFromList(synchronizingList);
            throw new ServerException(ResultConstant.TimeLock.EXIST_DEVICE_SYNCHRONIZING.setErrorInfo(names + " These device synchronizing"));
        }
        //2.校验是否存在需要同步的intranetIp
        List<Map<String, String>> maps = timeLockEventMapper.listSynchronizingDeviceByIntranetIps(intranetIps.keySet(), eventId);
        if (!CollectionUtils.isEmpty(maps)) {
            String names = this.getDeviceNameFromListMap(maps, intranetIps, excludePeerId);
            if (StringUtils.isNotEmpty(names)) {
                throw new ServerException(ResultConstant.TimeLock.EXIST_INTRANET_IP_SYNCHRONIZING.setErrorInfo(names));
            }
        }
        return allPeerIds;
    }

    /**
     * 去TPC中校验指定设备是否有TimeLock Feature
     * @param allPeerIds 指定设备
     */
    private void checkTimeLockFeatureExist(List<String> allPeerIds) {
        // check TPC timelock feature
        if (timeLockCheckTpcFeature) {
            //1.校验Receiver的feature
            Result<List<String>> rFeatureEnableResult = userFeignService.getTpcFeatureEnable(new GetTpcFeatureEnableParam(LocalConstant.Feature.R_TIMELOCK, allPeerIds));
            if (!rFeatureEnableResult.assertSuccess()) {
                throw new ServerException(ResultConstant.TimeLock.GET_FEATURE_FROM_TPC_FAILED.setResult(rFeatureEnableResult));
            }
            //2.校验Pack的feature
            Result<List<String>> tFeatureEnableResult = userFeignService.getTpcFeatureEnable(new GetTpcFeatureEnableParam(LocalConstant.Feature.T_TIMELOCK, allPeerIds));
            if (!tFeatureEnableResult.assertSuccess()) {
                throw new ServerException(ResultConstant.TimeLock.GET_FEATURE_FROM_TPC_FAILED.setResult(rFeatureEnableResult));
            }
            List<String> featureEnableRids = rFeatureEnableResult.getResult() == null ? new ArrayList<>() : rFeatureEnableResult.getResult();
            List<String> featureEnableTids = tFeatureEnableResult.getResult() == null ? new ArrayList<>() : tFeatureEnableResult.getResult();
            featureEnableRids = featureEnableRids.stream().map(String::toLowerCase).collect(Collectors.toList());
            featureEnableTids = featureEnableTids.stream().map(String::toLowerCase).collect(Collectors.toList());
            allPeerIds = allPeerIds.stream().map(String::toLowerCase).collect(Collectors.toList());
            allPeerIds.removeAll(featureEnableRids);
            allPeerIds.removeAll(featureEnableTids);
            if (!CollectionUtils.isEmpty(allPeerIds)) {
                String names = this.getDeviceNameFromList(allPeerIds);
                throw new ServerException(ResultConstant.TimeLock.EXIST_DEVICE_NOT_ACCESS_TIME_LOCK_FEATURE.setErrorInfo(names + " These device not access tpc timeLock feature."));
            }
        }
    }

    /**
     * 根据信息获取错误信息
     *
     * @param maps        多路R已经存在的集合
     * @param intranetIps 添加的R内网Ip对应的设备
     * @param excludePeerId 校验内网ip排除之外的rid
     * @return 返回错误信息
     */
    private String getDeviceNameFromListMap(List<Map<String, String>> maps, Map<String, String> intranetIps, List<String> excludePeerId) {

        StringBuilder sb = new StringBuilder();
        maps.forEach(s -> {
            String preIntranetIp = s.get("intranet_ip");
            String prePeerId = s.get("peer_id");
            if (!CollectionUtils.isEmpty(excludePeerId) && excludePeerId.contains(prePeerId)) {
                log.error("getDeviceNameFromListMap>>>>>>deletePeerId:[{}],addPeerId:[{}]", excludePeerId, prePeerId);
                return;
            }
            Device preDevice = deviceService.getCurrentDevice(prePeerId);
            String peerId = intranetIps.get(preIntranetIp);
            String deviceName = "";
            if (StringUtils.isNotEmpty(peerId)) {
                Device device = deviceService.getCurrentDevice(peerId);
                if (device != null) {
                    deviceName = device.getName();
                }
            }
            String preDeviceName = prePeerId;
            if (preDevice != null) {
                preDeviceName = preDevice.getName();
            }
            sb.append(preDeviceName).append(" with the same intranet IP as ")
                    .append(deviceName).append(" is already in timeLock; ");
        });
        return sb.toString();
    }

    /**
     * 根据peerId获取IP对应的内网Ip
     *
     * @param devices        设备的集合
     * @param mainIntranetIp 主设备的内网Ip
     * @return 返回receiver和对应的内网Ip，list0的key为IntranetIp，value为peerId，list1的key为peerId，value为IntranetIp
     */
    private List<Map<String, String>> getIntranetIps(List<Device> devices, String mainIntranetIp, String mainPeerId) {
        List<Map<String, String>> resultList = new ArrayList<>();
        Map<String, String> intranetIpMap = new HashMap<>();
        Map<String, String> peerIdMap = new HashMap<>();
        if (!CollectionUtils.isEmpty(devices)) {
            devices.forEach(device -> {
                TimeLockMsgVO timeLockMsgVO = this.getIntranetIpAndPortByRid(device.getPeerId());
                if (intranetIpMap.containsKey(timeLockMsgVO.getIntranetIp())
                        || StringUtils.equalsIgnoreCase(mainIntranetIp, timeLockMsgVO.getIntranetIp())) {
                    log.error("getIntranetIps>>>>>>>>>>,peerId:[{}],intranetIp:[{}],intranetIpMap:[{}]", device.getPeerId(), timeLockMsgVO.getIntranetIp(), intranetIpMap);
                }
                intranetIpMap.put(timeLockMsgVO.getIntranetIp(), device.getPeerId());
                peerIdMap.put(device.getPeerId(), timeLockMsgVO.getIntranetIp());
                resultList.add(intranetIpMap);
                resultList.add(peerIdMap);
            });
        }
        return resultList;
    }

    /**
     * 获取设备的内网/外网Ip/port
     * @param peerId 设备id
     * @return timeLockMsg对象，获取的Ip/Port放到该对象中
     */
    private TimeLockMsgVO getReceiverIpAndPort(String peerId) {
        //1.调用 main R 接口，获取内网Ip、Port
        TimeLockMsgVO timeLockMsg = this.getIntranetIpAndPortByRid(peerId);
        //2.获取外网IP
        Device mainDevice = deviceService.getCurrentDevice(peerId);
        if (mainDevice != null) {
            timeLockMsg.setExtranetIp(mainDevice.getIp());
            timeLockMsg.setMainReceiverName(mainDevice.getName());
        }
        //3.获取外网端口
        timeLockMsg.setIntranetPort(DeviceConstant.TimeLockConstant.DEFAULT_NTP_PORT);
        //4.check Intranet Extranet ip port
        if ( StringUtils.isBlank(timeLockMsg.getIntranetIp()) || StringUtils.isBlank(timeLockMsg.getExtranetIp())
                || timeLockMsg.getIntranetPort() == null || timeLockMsg.getExtranetPort() == null ) {
            throw new ServerException(ResultConstant.TimeLock.GET_IP_PORT_ERROR.setErrorInfo("Get ip port error" + timeLockMsg.toString()));
        }
        return timeLockMsg;
    }

    /**
     * 获取设备的内网Ip
     * @param peerId 设备Id
     * @return timeLockMsg对象，获取的Ip/Port放到该对象中
     */
    private TimeLockMsgVO getIntranetIpAndPortByRid (String peerId) {
        TimeLockMsgVO timeLockMsg = new TimeLockMsgVO();
        //1.获取内网Ip端口信息
        Result<String> queryReceiverInfoResult = receiverControlService.command(peerId, CommandConstant.QUERY_RECEIVER_INFO, null);
        if (!queryReceiverInfoResult.assertSuccess()) {
            log.error("getReceiverIpAndPort>>>>>>>get inner/out Internet ip/port failed,peerId:[{}],result:[{}]", peerId, queryReceiverInfoResult);
            throw new ServerException(queryReceiverInfoResult);
        }
        //2.解析结果，获取内网、外网Ip、Port
        String queryReceiverInfo = queryReceiverInfoResult.getResult();
        JsonNode jsonTree = null;
        try {
            jsonTree = MyUtil.MAPPER.readTree(queryReceiverInfo);
        } catch (IOException e) {
            log.error("getReceiverIpAndPort>>>>>>parse result exception,peerId:[{}],result:[{}],e:[{}]", peerId, queryReceiverInfoResult, e);
            throw new ServerException(ResultConstant.TimeLock.RECEIVER_QUERY_INFO_DATA_ERROR);
        }
        //3.获取内网ip
        JsonNode localIPAddresses = jsonTree.get("LocalIPAddresses");
        if (localIPAddresses == null || localIPAddresses.size() == 0) {
            log.error("getReceiverIpAndPort>>>>>>localIPAddresses is empty,peerId:[{}],result:[{}],localIPAddresses:[{}]",
                    peerId, queryReceiverInfoResult, localIPAddresses);
            throw new ServerException(ResultConstant.TimeLock.RECEIVER_CONFIG_NOT_EXIST_LOCAL_IP_ADDRESSES);
        }
        String intranetIp = localIPAddresses.get(0).asText();
        timeLockMsg.setIntranetIp(intranetIp);
        //4.获取内网端口
        JsonNode ntpExternalPort = jsonTree.get("NTPExternalPort");
        if (ntpExternalPort == null) {
            timeLockMsg.setExtranetPort(DeviceConstant.TimeLockConstant.DEFAULT_NTP_PORT);
        } else {
            timeLockMsg.setExtranetPort(ntpExternalPort.asInt());
        }
        return timeLockMsg;
    }

    @Override
    public void updateSynchronize(String userId, TimeLockUpdateSyncParam param,String  role) {
        if (StringUtils.equals(LocalConstant.UserRole.SUPPORT, role) || StringUtils.equals(LocalConstant.UserRole.SUPER_ADMIN, role)) {
            List<TimeLockMsg> timeLockMsgs;
            String deletePeerId = param.getDeletePeerIds();
            String[] peerIds = StringUtils.split(deletePeerId, ",");
            List<String> rids =  new ArrayList<>(Arrays.asList(peerIds));
            List<TimeLockDeviceMsgVo> timeLockDeviceMsgVos = this.listOpenTimeLockReceiverByRids(rids);
            if (!CollectionUtils.isEmpty(timeLockDeviceMsgVos)) {
                TimeLockDeviceMsgVo timeLockDeviceMsgVo = timeLockDeviceMsgVos.get(0);
                String   eventId = timeLockDeviceMsgVo.getEventId();
                String   ownUserId = timeLockDeviceMsgVo.getOwnUserId();
                //2.获取该event下所有的msg信息
                timeLockMsgs = timeLockMsgService.listSynchronizingMsgByEventId(eventId);
                updateSyn(param, eventId, ownUserId, timeLockMsgs, userId);
            }
            return;
        }
        String redisKey = "time:lock:sync:" + userId;
        try {
            redisLock.lock(redisKey);
            List<TimeLockMsg> timeLockMsgs = new ArrayList<>();
            if (StringUtils.isNotEmpty(param.getAddPeerIds())) {
                param.setAddPeerIds(param.getAddPeerIds().toLowerCase());
            }
            if (StringUtils.isNotEmpty(param.getDeletePeerIds())) {
                param.setDeletePeerIds(param.getDeletePeerIds());
            }
            String deletePeerId = param.getDeletePeerIds();
            String addPeerId = param.getAddPeerIds();
            String[] addPeerIds = StringUtils.split(addPeerId, ",");
            String[] deletePeerIds = StringUtils.split(deletePeerId, ",");
            List<String> addRids = new ArrayList<>(Arrays.asList(addPeerIds));
            List<String> deleteRids = new ArrayList<>(Arrays.asList(deletePeerIds));
            if (!CollectionUtils.isEmpty(addRids)) {
                //1.获取用户下同步的timeLockEvent
                TimeLockEvent timeLockEvent = this.getTimeLockEventByUserId(userId);
                if (timeLockEvent == null) {
                    throw new ServerException(ResultConstant.TimeLock.NOT_SYNCHRONIZING);
                }
                //2.获取该event下所有的msg信息
                timeLockMsgs = timeLockMsgService.listSynchronizingMsgByEventId(timeLockEvent.getId());
                updateSyn(param, timeLockEvent.getId(), null, timeLockMsgs, userId);
                return;
            }
            //需要根据peerId,去user_device表查询,这个设备是否在这个用户下,否则返回没有权限
            Set<String> deviceIdByUser = userDeviceService.getDeviceIdByUser(userId);
            if (!CollectionUtils.isEmpty(deviceIdByUser)) {
                deviceIdByUser = deviceIdByUser.stream().map(String::toLowerCase).collect(Collectors.toSet());
                deleteRids = deleteRids.stream().map(String::toLowerCase).collect(Collectors.toList());
                deleteRids.retainAll(deviceIdByUser);
            }
            if (CollectionUtils.isEmpty(deleteRids)) {
                throw new ServerException(ResultConstant.TimeLock.PERMISSION_DENIED);
            }
            List<TimeLockDeviceMsgVo> timeLockDeviceMsgVos = this.listOpenTimeLockReceiverByRids(deleteRids);
            if (!CollectionUtils.isEmpty(timeLockDeviceMsgVos)) {
                TimeLockDeviceMsgVo timeLockDeviceMsgVo = timeLockDeviceMsgVos.get(0);
                String eventId = timeLockDeviceMsgVo.getEventId();
                String ownUserId = timeLockDeviceMsgVo.getOwnUserId();
                //2.获取该event下所有的msg信息
                timeLockMsgs = timeLockMsgService.listSynchronizingMsgByEventId(eventId);
                updateSyn(param, eventId, ownUserId, timeLockMsgs, userId);
            }

        } finally {
            redisLock.unlock(redisKey);
        }

    }

    private void updateSyn(TimeLockUpdateSyncParam param, String eventId, String ownUserId, List<TimeLockMsg> timeLockMsgs,String userId) {
        if (CollectionUtils.isEmpty(timeLockMsgs)) {
            throw new ServerException(ResultConstant.TimeLock.NOT_SYNCHRONIZING);
        }

        List<TimeLockMsg> collect = timeLockMsgs.stream().filter(s -> s.getMainServer() != null && s.getMainServer() == 1).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(collect)) {
            //    log.error("updateSynchronize>>>>>>>no main receiver,timeLockEvent:[{}],timeLockMsgs:[{}]", timeLockEvent, timeLockMsgs);
            throw new ServerException(ResultConstant.TimeLock.FAILED_TO_GET_MAIN_R);
        }
        TimeLockMsg timeLockMsg = collect.get(0);
        Map<String, TimeLockMsg> timeLockMsgMap = timeLockMsgs.stream()
                .collect(Collectors.toMap(TimeLockMsg::getPeerId, Function.identity(), (s1, s2) -> s2));
        //3.校验并获取取消SyncTimeLock的设备peerId集合
        List<String> deletePeerIds = this.checkDeleteSyncDevice(param.getDeletePeerIds(), timeLockMsg.getPeerId(),
                timeLockMsgMap.keySet(), ownUserId, param.isDeleteMainReceiver(), timeLockMsgs);
        //4.校验并获取需要SyncTimeLock的设备peerId集合
        Map<String, String> peerIdsMap = new HashMap<>();
        String addPeerIdsString = param.getAddPeerIds();
        Map<String, String> packDependenceRidMap = new HashMap<>();
        List<String> addPeerIds = this.checkAddSyncDevice(packDependenceRidMap, timeLockMsg.getPeerId(), peerIdsMap, addPeerIdsString, deletePeerIds, eventId);

        List<String> willAddReceiver = new ArrayList<>();
        List<String> willDeleteReceivers = new ArrayList<>();
        List<String> allReceivers = new ArrayList<>();
        //获取将要进行TimeLock的Receiver
        if(!CollectionUtils.isEmpty(addPeerIds)){
            List<Device> willAddDevices = deviceService.listCurrentDevice(addPeerIds);
            willAddReceiver = willAddDevices.stream().filter(s -> StringUtils.equalsIgnoreCase(LocalConstant.DeviceType.R, s.getType()))
                    .map(Device::getPeerId).collect(Collectors.toList());
        }

        //获取将要解除TimeLock的R
        if(!CollectionUtils.isEmpty(deletePeerIds)){
            List<Device> willDeleteDevices = deviceService.listCurrentDevice(deletePeerIds);
            willDeleteReceivers = willDeleteDevices.stream().filter(s -> StringUtils.equalsIgnoreCase(LocalConstant.DeviceType.R, s.getType()))
                    .map(Device::getPeerId).collect(Collectors.toList());
        }

        //获取这个event下全部的R
        List<String> peerIds = timeLockMsgs.stream().map(TimeLockMsg::getPeerId).collect(Collectors.toList());
        if(!CollectionUtils.isEmpty(peerIds)){
            List<Device> allDevices = deviceService.listCurrentDevice(peerIds);
            allReceivers = allDevices.stream().filter(s -> StringUtils.equalsIgnoreCase(LocalConstant.DeviceType.R, s.getType()))
                    .map(Device::getPeerId).collect(Collectors.toList());
        }


        //此步骤考虑需求为,如果删除和添加同步进行,
        //那么全部的,减去要删除的,等于还剩下的在TimeLock的R,再加上要添加的R,如果小于两个R,那么是不符合TimeLock规则的,所以直接unSynchronize.
        int count = allReceivers.size() - willDeleteReceivers.size()+willAddReceiver.size();
        if(count<2){
            this.unSynchronize(ownUserId);
        }else {
        //5.删除同步
            if (!CollectionUtils.isEmpty(deletePeerIds)) {
                deletePeerIds.forEach(peerId -> {
                    //删除原来的start和report
                    this.cancelSync(peerId, Boolean.TRUE, userId);
                });
            }
        }
        //6.添加同步
        if (!CollectionUtils.isEmpty(addPeerIds)) {
            //6.1.获取主R的内外网Ip
            //1.获取主R内网外网Ip/Port
            TimeLockMsgVO timeLockMsgVO = this.getReceiverIpAndPort(timeLockMsg.getPeerId());
            //6.1.report TimeLockMsg入库
            timeLockMsgService.reportSyncDeviceTimeLockMsg(addPeerIds, peerIdsMap, timeLockMsg, packDependenceRidMap);
            //6.2.start TimeLockMsg入库 并且发送msgpipe消息
            timeLockMsgVO.setEventId(eventId);
            timeLockMsgVO.setMsgType(DeviceConstant.TimeLockEventType.START_SYNC);
            timeLockMsgVO.setMainServer(false);
            timeLockMsgService.startSyncDeviceTimeLockMsg(addPeerIds, timeLockMsgVO, peerIdsMap, timeLockMsg, packDependenceRidMap);
        }
    }

    /**
     * 校验新增Sync的device是否符合要求并返回要新增的peerId集合
     *
     * @param packDependenceRidMap key为pack，value为R
     * @param mainRid              主R的peerId
     * @param peerIdsMap           从R/Pack对应的内网Ip
     * @param addPeerIdsString     新增同步的设备id集合
     * @param deletePeerIds        取消同步的设备id集合
     * @param eventId        存在的eventId
     * @return 返回需要新增的peerId集合
     */
    private List<String> checkAddSyncDevice(Map<String, String> packDependenceRidMap, String mainRid, Map<String, String> peerIdsMap,
                                            String addPeerIdsString, List<String> deletePeerIds, String eventId) {
        List<String> addPeerIds = null;
        if (StringUtils.isNotEmpty(addPeerIdsString)) {
            addPeerIds = new ArrayList<>(Arrays.asList(addPeerIdsString.toLowerCase().split(",")));
            //0.校验添加的peerId和删除的peerId是否有重复
            if (!CollectionUtils.isEmpty(deletePeerIds)) {
                ArrayList<String> strings = new ArrayList<>(addPeerIds);
                strings.retainAll(deletePeerIds);
                if (!CollectionUtils.isEmpty(strings)) {
                    String deviceNameFromList = this.getDeviceNameFromList(strings);
                    throw new ServerException(ResultConstant.Device.DEVICE_NOT_EXIST.setErrorInfo(deviceNameFromList + "These sync device duplicates the unSync device"));
                }
            }
            //1.校验设备并获取所有的rid集合
            List<Device> rDevices = this.checkSyncReceiverAndPackAndGetReceiver(addPeerIds, null, packDependenceRidMap);
            //2.获取R对应的所有内网Ip
            List<Map<String, String>> peerIdAndIntranetIps = this.getIntranetIps(rDevices, "", "");
            Map<String, String> intranetIps = peerIdAndIntranetIps.get(0);
            peerIdsMap.putAll(peerIdAndIntranetIps.get(1));
            //3.获取所有的peerId
            List<String> allPeerIds = this.checkDeviceSynchronizing(mainRid, addPeerIds, intranetIps, deletePeerIds, Boolean.FALSE, eventId);
            //4.校验设备是否含有TimeLockFeature
            this.checkTimeLockFeatureExist(allPeerIds);
        }
        return addPeerIds;
    }

    /**
     * 校验删除Sync的device是否符合要求并返回要删除的peerId
     *
     * @param deletePeerIdsString 取消同步的设备id集合
     * @param mainRid             主R的peerId
     * @param syncPeerIds         已在sync的从R/Pack的peerId集合
     * @param timeLockMsgs        所有的TimeLockMsg信息
     * @return 返回需要删除的peerId集合
     */
    private List<String> checkDeleteSyncDevice(String deletePeerIdsString, String mainRid, Set<String> syncPeerIds,
                                               String userId, boolean deleteMainRidFlag, List<TimeLockMsg> timeLockMsgs) {

        List<String> deletePeerIds = null;
        if (StringUtils.isNotEmpty(deletePeerIdsString)) {
            deletePeerIds = new ArrayList<>(Arrays.asList(deletePeerIdsString.toLowerCase().split(",")));
            if (deletePeerIds.contains(mainRid.toLowerCase())) {
                if (deleteMainRidFlag) {
                    this.unSynchronize(userId);
                    throw new ServerException(ResultUtil.success());
                }
                throw new ServerException(ResultConstant.TimeLock.MAIN_R_CAN_NOT_BE_REMOVED);
            }
            List<String> tempDeletePeerIds = new ArrayList<>(deletePeerIds);
            tempDeletePeerIds.retainAll(syncPeerIds);
            if (CollectionUtils.isEmpty(tempDeletePeerIds) || tempDeletePeerIds.size() != deletePeerIds.size()) {
                deletePeerIds.removeAll(tempDeletePeerIds);
                String deviceNames = this.getDeviceNameFromList(deletePeerIds);
                throw new ServerException(ResultConstant.TimeLock.NOT_SYNCHRONIZING
                        .setErrorInfo(deviceNames + " Those device is not synchronizing"));
            }
        }
        return deletePeerIds;
    }

    /**
     * 根据用户Id获取正在sync的TimeLockEvent
     * @param userId 用户id
     * @return TimeLockEvent对象
     */
    private TimeLockEvent getTimeLockEventByUserId(String userId) {
        TimeLockEvent timeLockEvent = new TimeLockEvent();
        timeLockEvent.setUserId(userId);
        timeLockEvent.setType(DeviceConstant.TimeLockEventType.START_SYNC);
        timeLockEvent = super.selectExistOne(timeLockEvent);
        if (timeLockEvent == null) {
            throw new ServerException(ResultConstant.TimeLock.NOT_SYNCHRONIZING);
        }
        return timeLockEvent;
    }


    @Override
    @Transactional
    public Result<String> unSynchronize(String userId) {
        String redisKey = "time:lock:sync:" + userId;
        try {
            // 检查是否在同步
            TimeLockEvent record = new TimeLockEvent();
            record.setUserId(userId);
            record.setType(DeviceConstant.TimeLockEventType.START_SYNC);
            TimeLockEvent timeLockEvent = super.selectExistOne(record);
            if (timeLockEvent == null) {
                return ResultUtil.error("81100601", "Not synchronizing");
            }

            // 查出所有正在同步的peerId，并发送停止命令
            String eventId = timeLockEvent.getId();
            timeLockMsgService.stopTimeLockMsg(eventId,userId);
            // 修改TimeLockEvent
            timeLockEvent.setType(DeviceConstant.TimeLockEventType.STOP_SYNC);
            super.updateSelective(timeLockEvent);
            // 添加user behavior
            userBehaviorService.setUserTimeLockBehavior(userId, false);
            return ResultUtil.success();
        }finally {
            redisLock.unlock(redisKey);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void cancelSync(String rid, boolean needSendMsgpipe,String userId) {

        TimeLockEvent timeLockEvent = timeLockEventMapper.getExecutingEventByPeerId(rid);
        if (timeLockEvent == null) {
            log.error("cancelSync>>>>>>Receive cancel time lock, but not find executing time lock event rId:{}", rid);
            return;
        }
        String eventId = timeLockEvent.getId();
        TimeLockMsg timeLockMsg = timeLockMsgService.getTimeLockMsg(eventId, rid, DeviceConstant.TimeLockEventType.START_SYNC);
        if (timeLockMsg == null) {
            log.error("cancelSync>>>>>>Receive cancel time lock, but not find executing time lock msg eventId:{} rId:{}", eventId, rid);
            this.stopPackSyncByRid(rid, eventId, needSendMsgpipe,userId);
            return;
        }
        Integer mainServer = timeLockMsg.getMainServer();
        if (mainServer == 1) {
            //main server canceled, cancel all TimeLock session
            this.unSynchronize(timeLockEvent.getUserId());
        } else {
            //slave server canceled,  remove this R and T at page and send cancel to this R and T
            // TODO 添加userBehavior， 剔除子R
            timeLockMsgService.stopTimeLockMsg(eventId, rid, needSendMsgpipe, userId,
                    !StringUtils.equalsIgnoreCase(timeLockMsg.getReceiverStatus(), "-1"));
            //根据peerId和eventId逻辑删除msg记录
            timeLockMsgService.logicDeleteMsgByEventIdAndPeerId(eventId, rid);
            this.stopPackSyncByRid(rid, eventId, needSendMsgpipe, userId);
        }
    }

    /**
     * 根据rid/eventId去stop掉对应的pack
     * @param rid
     * @param eventId
     * @param needSendMsgpipe
     */
    private void stopPackSyncByRid(String rid, String eventId,boolean needSendMsgpipe ,String userId) {
        List<TimeLockMsg> timeLockMsgs = timeLockMsgService.getTimeLockMsgByEventIdAndLiveRid(eventId, rid, DeviceConstant.TimeLockEventType.START_SYNC);
        if (!CollectionUtils.isEmpty(timeLockMsgs)) {
            timeLockMsgs.forEach(timeLockMsg -> {
                timeLockMsgService.stopTimeLockMsg(eventId, timeLockMsg.getPeerId(), needSendMsgpipe, userId,
                        !StringUtils.equalsIgnoreCase(timeLockMsg.getReceiverStatus(), "-1"));
                //根据peerId和eventId逻辑删除msg记录
                timeLockMsgService.logicDeleteMsgByEventIdAndPeerId(eventId, timeLockMsg.getPeerId());
            });
        }
    }


    @Override
    public Result<String> receiveMsg(String peerId, String eventId, int status)
    {
        //根据eventId主键查找event对象
        TimeLockEvent timeLockEvent = super.selectExistByPrimaryKey(eventId);
        String msgType = DeviceConstant.TimeLockEventType.START_SYNC;
        if (timeLockEvent == null || !StringUtils.equalsIgnoreCase(timeLockEvent.getType(), msgType)) {
            log.error("timeLockEvent is null or timeLockEvent.getType is not same with startSync", timeLockEvent);
            return ResultUtil.error("81100601", "the timeLockEvent is null or type is not startSync");
        }
        //更新timeLockMsg
        timeLockMsgService.updateTimeLockMsgByEventIdAndPeerIdAndStatus(peerId, eventId, msgType, status);
        return ResultUtil.success();
    }

    @Override
    public Result<String> checkDevieTimeLockStatus(String userId, String peerIds) {
        List<String> peerIdList = new ArrayList<>();
        if (StringUtils.isNotEmpty(peerIds)) {
            List<String> synPeerIdList = Arrays.asList(peerIds.split(","));
            peerIdList.addAll(synPeerIdList);
        }
        return ResultUtil.success(this.checkDevieTimeLockStatus(userId, peerIdList));
    }

    @Override
    public List<DeviceIdNameAndMsg> setBitrateAndDelay(String peerIds, int bitRate, int delay) {
        if (StringUtils.isBlank(peerIds)) {
            return null;
        }
        // 设置失败的 R
        List<DeviceIdNameAndMsg> list = new ArrayList<>();
        SetBitrateAndDelayParam param = new SetBitrateAndDelayParam()
                .setBitrate(bitRate)
                .setDelay(delay);
        String[] rids = peerIds.split(",");
        for (String rid : rids) {
            param.setRid(rid);
            Result<String> result = receiverControlService.setBitrateAndDelay(param);
            if (!result.assertSuccess()) {
                Device r = deviceService.getCurrentDevice(rid);
                if (r != null) {
                    list.add(new DeviceIdNameAndMsg(r.getPeerId(), r.getName(), result.getErrorInfo()));
                }
                continue;
            }
            String data = result.getResult();
            if (StringUtils.isBlank(data)) {
                Device r = deviceService.getCurrentDevice(rid);
                if (r != null) {
                    list.add(new DeviceIdNameAndMsg(r.getPeerId(), r.getName(), "Communication failed"));
                }
                continue;
            }
            GridResult gridResult = null;
            try {
                gridResult = JsonUtil.toObject(data, GridResult.class);
            } catch (IOException e) {
                log.error(e.toString(), e);
            }
            if (gridResult == null) {
                Device r = deviceService.getCurrentDevice(rid);
                if (r != null) {
                    list.add(new DeviceIdNameAndMsg(r.getPeerId(), r.getName(), data));
                }
                continue;
            } else {
                if (!StringUtils.containsIgnoreCase(gridResult.getErrorCode(), "0x0")) {
                    Device r = deviceService.getCurrentDevice(rid);
                    if (r != null) {
                        list.add(new DeviceIdNameAndMsg(r.getPeerId(), r.getName(), gridResult.getErrorInfo()));
                    }
                    continue;
                }
            }
        }
        return list;
    }

    @Override
    public Result<String> removeSyn(String userId, String peerIds) {
        if (StringUtils.isEmpty(peerIds)) {
            return ResultUtil.error("0x80100001", "peerIds can not empty");
        }
        TimeLockEvent example = new TimeLockEvent()
                .setType(DeviceConstant.TimeLockEventType.START_SYNC)
                .setUserId(userId);
        TimeLockEvent timeLockEvent = super.selectExistOne(example);
        if (timeLockEvent == null) {
            return ResultUtil.error("81100601", "Not synchronizing");
        }
        List<String> peerIdList = Arrays.asList(peerIds.split(","));
       timeLockMsgService.batchDeleteByPeerIdsAndEventId(peerIdList, timeLockEvent.getId());
        return ResultUtil.success();
    }

    @Override
    public List<TimeLockMsgResult> checkDevieTimeLockStatus(String userId, List<String> peerIdList) {
        List<TimeLockMsgResult> resultList = new ArrayList<>();
        List<TimeLockMsg>  list = timeLockEventMapper.listTimeLockMsgByPeerIds(peerIdList);
        if (CollectionUtils.isEmpty(list)) {
            return resultList;
        }

        for (TimeLockMsg timeLockMsg : list) {
            TimeLockMsgResult result = timeLockMsg.convert2TimeLockMsgResult();
            Device device = deviceService.getCurrentDevice(result.getPeerId());
            if ( device == null || "0".equals(device.getStatus()) ) {
                result.setStatus("failed");
            }
            resultList.add(result);
        }

        return resultList;
    }

    @Override
    public void processTimeLockMessage(MsgpipeDTO message) {
//        if (!enableProcessTimeLockMessage) {
//            return;
//        }
        Map<String, String> headerMap = null;
        TimeLockBody body = null;
        try {
            headerMap = JsonUtil.toObject(message.getHeader(), Map.class);

        } catch (IOException e) {
            log.error(e.toString(), e);
            return;
        }

        try {
            body =JsonUtil.toObject(message.getBody(), TimeLockBody.class);
        } catch (IOException e) {
            log.error(e.toString(), e);
            return;
        }
        //Time Lock msg from Receiver/Pack
        log.error("ComeForm Receive Of TimeLock message:{}", message);

        String peerId = headerMap.get("Sender");
        if (peerId.startsWith("0x")) {
            peerId = peerId.substring(2);
        }

        String msgType = body.getMsgType();
        if (DeviceConstant.TimeLockEventType.CANCEL_SYN.equals(msgType)) {
            //cancelSync
            try {
                cancelSync(peerId, Boolean.FALSE,null);
            } catch (Exception e) {
                log.error(e.toString(), e);
                log.error(peerId + " 处理失败！");
            }
        } else {
            //reportSync
            timeLockMsgService.reportSyncUpdateStatus(peerId, body);
        }
    }

    @Override
    public List<TimeLockDeviceMsgVo> listOpenTimeLockReceiverByRids(List<String> rids) {
        if (CollectionUtils.isEmpty(rids)) {
            return new ArrayList<>();
        }
       return timeLockMsgService.listSynchronizingReportReceiverMsgByRids(rids);
    }

    @Override
    public List<TimeLockDeviceMsgVo> listOpenTimeLockPackByRids(List<String> rids) {
        if (CollectionUtils.isEmpty(rids)) {
            return new ArrayList<>();
        }
        return timeLockMsgService.listOpenTimeLockPackByRids(rids);
    }

    @Override
    public Map<String,Object> getTimeLockMsgByPeerId(PeerIdParam param) {
        Map<String,Object>  resultMap =new HashMap<>();
        String peerId = param.getPeerId();
        //1.根据rid获取timeLockEvent
        TimeLockEvent timeLockEvent = timeLockEventMapper.getExecutingEventByPeerId(peerId);
        if (timeLockEvent == null) {
            log.error("getTimeLockMsgByPeerId>>>>>no TimeLockEvent,peerId:[{}]", peerId);
            return resultMap;
        }
        //2.根据timeLock获取TimeLockMsg
        List<TimeLockDeviceVo> timeLockMsgs = timeLockMsgService.listSynchronizingStartReceiverMsgByEventId(timeLockEvent.getId());

        if (!CollectionUtils.isEmpty(timeLockMsgs)) {
            for (TimeLockDeviceVo timeLockMsg : timeLockMsgs) {
                String rid = timeLockMsg.getPeerId();
                List<String> ridList = new ArrayList<>();
                ridList.add(rid);
                List<TimeLockDeviceMsgVo> timeLockDeviceMsgVos = timeLockMsgService.listOpenTimeLockPackByRids(ridList);
                if (!CollectionUtils.isEmpty(timeLockDeviceMsgVos)) {
                    for (TimeLockDeviceMsgVo timeLockDeviceMsgVo : timeLockDeviceMsgVos) {
                        String packPeerId = timeLockDeviceMsgVo.getPeerId();
                        MyDevice dbDevice = deviceService.getDBDevice(packPeerId);
                        if (dbDevice!=null) {
                            String name = dbDevice.getName();
                            String tid = dbDevice.getPeerId();
                            timeLockMsg.setPackName(name);
                            timeLockMsg.setPackPeerId(tid);
                        }
                    }
                }
            }
        }

        
        if (CollectionUtils.isEmpty(timeLockMsgs)) {
            log.error("getTimeLockMsgByPeerId>>>>>no TimeLockMsg,peerId:[{}],timeLockEvent:[{}]", peerId, timeLockEvent);
            return resultMap;
        }
        List<TimeLockDeviceVo> mainTimeLockMsgs = timeLockMsgs.stream().filter(timeLockMsg -> timeLockMsg.getMainServer() == 1)
                .collect(Collectors.toList());
        Map<String, String> mainDeviceMap = new HashMap<>();
        Map<String, String> map = new HashMap<>();
        if (!CollectionUtils.isEmpty(mainTimeLockMsgs)) {
            TimeLockDeviceVo timeLockMsg = mainTimeLockMsgs.get(0);
            String message = timeLockMsg.getMessage();
            if (StringUtils.isNotEmpty(message)) {
                try {
                    //获取用户信息
                    LoginUser loginUser = userFeignService.getLoginUserByUserId(timeLockEvent.getUserId());
                    if (loginUser != null) {
                        mainDeviceMap.put("name", loginUser.getEmail());
                    }
                    map = JsonUtil.toObject(message, Map.class);
                } catch (Exception e) {
                    log.error("getTimeLockMsgByPeerId>>>>>parseJson Exception,message:[{}],e:[{}]", message, e);
                }
                if (map == null) {
                    map = new HashMap<>();
                }
            }
            mainDeviceMap.put("create_time", String.valueOf(timeLockMsg.getCreateTime()));
            mainDeviceMap.put("update_time", String.valueOf(timeLockMsg.getUpdateTime()));
        }else {
            mainDeviceMap.put("create_time", String.valueOf(timeLockEvent.getCreateTime()));
            mainDeviceMap.put("update_time", String.valueOf(timeLockEvent.getUpdateTime()));
            timeLockMsgs = new ArrayList<>();
        }
        mainDeviceMap.put("userId", timeLockEvent.getUserId());
        mainDeviceMap.put("intranetIp", map.get("intranetIp"));
        mainDeviceMap.put("intranetPort", map.get("intranetPort"));
        mainDeviceMap.put("extranetIp", map.get("extranetIp"));
        mainDeviceMap.put("extranetPort", map.get("extranetPort"));
        resultMap.put("mainReceiverMessage",mainDeviceMap);
        resultMap.put("timeLockDevice", timeLockMsgs);
        return resultMap;
    }

    @Override
    public List<TimeLockDeviceMsgVo> getAllReceiverTimeLockMsg() {
        return timeLockEventMapper.getAllReceiverTimeLockMsg();
    }

    @Override
    public List<TimeLockDeviceMsgVo> listOpenTimeLockPackByUserId(String userId) {
        return timeLockEventMapper.listOpenTimeLockPackByUserId(userId);
    }

    @Override
    public TimeLockEvent getTimeLockEventById(String eventId) {
        return super.selectByPrimaryKey(eventId);
    }

    /**
     * 获取指定peerId的名字集合组成的字符串
     * @param peerIds 指定peerId
     * @return name组成的字符串
     */
    private String getDeviceNameFromList(List<String> peerIds){
        StringBuffer namesBuffer = new StringBuffer();
        List<Device> devices = deviceService.listCurrentDevice(peerIds);
        if (!CollectionUtils.isEmpty(devices)) {
            List<String> collect = devices.stream().map(Device::getName).collect(Collectors.toList());
            namesBuffer.append(collect);
        }
        return namesBuffer.toString();

    }

}
